package mymyoux.ai
{
	/**
	 * A structured brain with layers
	 */ 
	public class LayerBrain extends Brain
	{
		/**
		 * @private
		 */
		private var _numInputs:uint;
		/**
		 * @private
		 */
		private var _numOutputs:uint;
		/**
		 * @private
		 */
		
		private var _numLayers:uint;
		/**
		 * @private
		 */
		private var _neuronsByLayer:uint;
		/**
		 * @private
		 */
		private var _layers:Array;
		public function LayerBrain(inputs:uint=0, outputs:uint=0, layers:uint = 0, neuronsByLayer:uint = 0)
		{
			_numInputs = inputs;
			_numOutputs = outputs;
			_layers = new Array();
			super(inputs, outputs, 0);
			
		}

		public function get neuronsByLayer():uint
		{
			return _neuronsByLayer;
		}

		public function set neuronsByLayer(value:uint):void
		{
			_neuronsByLayer = value;
		}

		public function get layers():uint
		{
			return _numLayers;
		}

		public function set layers(value:uint):void
		{
			_numLayers = value;
		}

		public override function get inputs():uint
		{
			return _numInputs;
		}
		public override function set inputs(value:uint):void
		{
			_numInputs = value;
			
		}
		public override function get outputs():uint
		{
			return _numOutputs;
		}
		public override function set outputs(value:uint):void
		{
			_numOutputs = value;
			
		}
		public function createNetwork():void
		{
			remListeners();
			_layers = new Array();
			_inputs = new Vector.<Neuron>();
			_outputs = new Vector.<Neuron>();
			_neurons = new Vector.<Neuron>();
			var i:uint, j:uint, k:uint;
			//var neuron:Neuron;
			
			for(i=0; i<layers; i++)
			{
				_layers.push(new Vector.<Neuron>());
				for(j=0; j<neuronsByLayer; j++)
				{
					_layers[i].push(new Neuron());
				}
			}
			for(i=0; i<_numInputs; i++)
			{
				_inputs.push(new Neuron());
				
				if(_inputs[i].getLinkedNeurons() == null || _inputs[i].getLinkedNeurons().length ==  0 || _inputs[i].getLinkedNeurons()[0] == null)
				{
					
					_inputs[i].register(new Nerve());
					
				}
			}

			if(_numLayers > 0)
			{
				
				for(i=0; i<_neuronsByLayer; i++)
				{
					for(j=0; j<_numInputs; j++)
					{
						(_layers[0][i] as Neuron).register(_inputs[j]);	
					}
					
				}	
			}
			for(j=1; j<_numLayers; j++)
			{
				for(i=0; i<_neuronsByLayer; i++)
				{
					for(k=0; k<_neuronsByLayer; k++)
					{
						(_layers[j][i] as Neuron).register(_layers[j-1][k]);	
					}
				}
			}
			for(i=0; i<_numOutputs; i++)
			{
				_outputs.push(new Neuron());
				if(_numLayers > 0)
				{
					for(j=0; j<_neuronsByLayer; j++)
					{
						
						_outputs[i].register(_layers[_layers.length-1][j]);		
					}
				}else
				{
					for(j=0; j<_numInputs; j++)
					{
						
						_outputs[i].register(_inputs[j]);		
					}
				}
			}
			addListeners();
		}
	}
}